using System;
using System.Data;
using System.Collections;
using System.IO;
using System.Text;
using System.Web;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;
using DotNetNuke;
using DotNetNuke.Common;
using DotNetNuke.Common.Utilities;
using DotNetNuke.Entities.Modules;
using DotNetNuke.Entities.Portals;
using DotNetNuke.Services.Localization;

using BiteTheBullet.DNN.Utils;
using BiteTheBullet.DNN.Modules.BTBYahooWeather.Data;

namespace BiteTheBullet.DNN.Modules.BTBYahooWeather.Business
{
	public class BTBWeatherFeedController : DotNetNuke.Entities.Modules.IPortable
	{
		
		private const string BASE_URL = "http://xml.weather.yahoo.com/forecastrss";

	
		private const string TABMODULE_DISPLAYMODE= "BTBYahooWeather_DisplayMode";

		public enum TemperatureScale
		{
			Celsius,
			Fahrenheit
		}

		#region "Public Methods"
		public BTBWeatherFeedInfo GetDefaultFeed(ArrayList weatherList)
		{
			if(weatherList.Count == 0)
				return null;
			
			foreach(BTBWeatherFeedInfo item in weatherList)
			{
				if(item.DefaultFeed)
					return item;
			}
			
			return (BTBWeatherFeedInfo)weatherList[0];
		}
		
		public void SetDefaultFeed(int moduleId, int weatherId)
		{
			DataProvider.Instance().SetDefaultFeed(moduleId, weatherId);
		}	

		public string CreateFeedUrl(string weatherStationCode, TemperatureScale tempScale)
		{
			return BASE_URL + "?p=" + weatherStationCode + "&u=" + 
							(tempScale == TemperatureScale.Celsius ? "c" : "f");	
		}

		public string ExtractWeatherCodeFromUrl(string url)
		{
			int startPos = url.IndexOf("=");
			int endPos = url.IndexOf("&");

            return url.Substring(++startPos, endPos - startPos);
		}
		public TemperatureScale ExtractTemperatureScaleFromUrl(string url)
		{
			string temp = url.Substring(url.Length - 1);
			if(temp == "c")
				return TemperatureScale.Celsius;
			else
				return TemperatureScale.Fahrenheit;
		}


		public void UpdateWeatherFeed(BTBWeatherFeedInfo info, PortalSettings portalSettings, ModuleInfo moduleConfiguration)
		{
			string proxyHost	 = portalSettings.HostSettings["ProxyServer"].ToString();
			string proxyPort = portalSettings.HostSettings["ProxyPort"].ToString();
			string proxyUsername = portalSettings.HostSettings["ProxyUsername"].ToString();
			string proxyPassword = portalSettings.HostSettings["ProxyPassword"].ToString();

			
			string proxyUrl = proxyPort.Trim() == string.Empty ? proxyHost : proxyHost + ":" + proxyPort;
			
			RssReader reader = new RssReader(info.Url, proxyUrl, proxyUsername, proxyPassword);
			
			info.Feed = reader.Response();

			XmlUrlResolver resolver = new XmlUrlResolver();
			resolver.Credentials = System.Net.CredentialCache.DefaultCredentials;

			XPathDocument doc = new XPathDocument(new XmlTextReader(info.Feed, XmlNodeType.Document, null));			
			MemoryStream ms = new MemoryStream();
			XslTransform transform = new XslTransform();


			string xslFile = null;

			ModuleController mc = new ModuleController();
			Hashtable settings = mc.GetTabModuleSettings(moduleConfiguration.TabModuleID);
			if(settings[TABMODULE_DISPLAYMODE] != null)
			{
				string displayMode = settings[TABMODULE_DISPLAYMODE].ToString();


				switch(displayMode)
				{
					case "full":
					case "full5":
						xslFile = HttpContext.Current.Server.MapPath("~/DesktopModules/BTBYahooWeather/weatherReport.xsl");
						break;

					case "medium":
					case "medium5":
						xslFile = HttpContext.Current.Server.MapPath("~/DesktopModules/BTBYahooWeather/weatherReportMedium.xsl");
						break;

					case "summary":
						xslFile = HttpContext.Current.Server.MapPath("~/DesktopModules/BTBYahooWeather/weatherReportSmall.xsl");
						break;
				}

			}
			else
				xslFile = HttpContext.Current.Server.MapPath("~/DesktopModules/BTBYahooWeather/weatherReport.xsl"); 

			transform.Load(xslFile);
			transform.Transform(doc, null, ms, resolver);

			ms.Position = 0;
			info.TransformedFeed = new StreamReader(ms, System.Text.Encoding.UTF8).ReadToEnd();

			ms.Close();
			

			int ttl = reader.Ttl();
			if(ttl > -1)
				info.Ttl = reader.Ttl();
			else

				info.Ttl = 20;

			info.UpdatedDate = DateTime.Now;
			info.CachedDate = DateTime.Now.AddMinutes(info.Ttl);
			info.LocationName = reader.LocationName();


			BTBWeatherFeedController controller = new BTBWeatherFeedController();
			controller.Update(info);
		}


		#region DAL methods

		public BTBWeatherFeedInfo Get(int weatherId)
		{
			return (BTBWeatherFeedInfo)DotNetNuke.Common.Utilities.CBO.FillObject(DataProvider.Instance().GetBTBWeatherFeed(weatherId), typeof(BTBWeatherFeedInfo));
		}
		public ArrayList GetByModuleId(int moduleId)
		{
			return DotNetNuke.Common.Utilities.CBO.FillCollection(DataProvider.Instance().GetBTBWeatherFeedByModule(moduleId), typeof(BTBWeatherFeedInfo));
		}

	
		public int Add(BTBWeatherFeedInfo objBTBWeatherFeed)
		{
			return (int)DataProvider.Instance().AddBTBWeatherFeed(objBTBWeatherFeed.ModuleId, 
													objBTBWeatherFeed.Ttl, 
													objBTBWeatherFeed.UpdatedDate, 
													objBTBWeatherFeed.CachedDate, 
													objBTBWeatherFeed.Feed, 
													objBTBWeatherFeed.Url, 
													objBTBWeatherFeed.TransformedFeed,
													objBTBWeatherFeed.LocationName);
		}
	
		public void Update(BTBWeatherFeedInfo objBTBWeatherFeed)
		{
			DataProvider.Instance().UpdateBTBWeatherFeed(objBTBWeatherFeed.WeatherId, 
												objBTBWeatherFeed.ModuleId, 
												objBTBWeatherFeed.Ttl, 
												objBTBWeatherFeed.UpdatedDate, 
												objBTBWeatherFeed.CachedDate, 
												objBTBWeatherFeed.Feed, 
												objBTBWeatherFeed.Url, 
												objBTBWeatherFeed.TransformedFeed,
												objBTBWeatherFeed.LocationName);
		}
		
		public void Delete(int weatherId)
		{
			DataProvider.Instance().DeleteBTBWeatherFeed(weatherId);
		}

		#endregion

		#endregion

		#region "Optional Interfaces"		
	
		public string ExportModule(int ModuleID)
		{
			string xmlExport = "";
			ArrayList feeds = this.GetByModuleId(ModuleID);

			if(feeds != null & feeds.Count > 0)
			{
				StringBuilder sb = new StringBuilder();
				sb.Append("<BTBYahooWeather>");

				foreach(BTBWeatherFeedInfo info in feeds)
				{
					sb.Append("<url>");
					sb.Append(Globals.XMLEncode(info.Url));
					sb.Append("</url>");
				}

				sb.Append("</BTBYahooWeather>");

				xmlExport = sb.ToString();
			}
			return xmlExport;
		}

		public void ImportModule(int ModuleID, string Content, string Version, int UserId)
		{
			
			XmlNode weatherNode = Globals.GetContent(Content, "BTBYahooWeather");

			XmlNodeList nodeList = weatherNode.SelectNodes("url");

			if(nodeList != null)
			{
				for(int i = 0; i < nodeList.Count; i++)
				{
					BTBWeatherFeedInfo info = new BTBWeatherFeedInfo();
					info.ModuleId = ModuleID;
					info.Url = nodeList[i].InnerText;

					Add(info);
				}
			}
		}
		#endregion
	}
}
